<!DOCTYPE html>
<html>
    <head>
        <title>LearnVue</title>
        <!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> -->
        <script src="https://cdn.jsdelivr.net/npm/vue@3.2.45/dist/vue.global.min.js"></script>
    </head>
    <body>
        <div id="counter">
            <p>{{num}}</p>
            <p>{{uname}}</p>
            <!--v-once 一次性插值，当数据改变时，不会随着更新-->
            <p v-once>{{uanme}}</p>
            <!--v-html 指令把msg字段按照html语法渲染，而不是普通字符串， 不过要谨慎使用此指令，会有xss攻击风险-->
            <span v-html="msg"></span>
            <!--动态绑定html的属性，比如id，name, src, bgcolor,size 等等-->
            <img v-bind:src="url" alt="v-bind: 凤凰网">

            <!-- 同样的功能，三种不同的实现方法-->
            <!--1 使用计算属性-->
            <p>{使用计算属性： {{append}}, 需要注意我们把方法当作属性使用</p>
            <p>{使用计算属性： {{append}}, 需要注意我们把方法当作属性使用</p>
            <!--2 javascript 表达式-->
            <p>javaScript 表达式： {{uname +", hi world!"}}</p>
            <!--3 自定义函数， 注意与计算属性写法的区别，需要括号， 每调用一次就会执行一次方法，但是计算属性只需要执行一次，因为它会使用缓存， 计算属性性能更好。-->
            <p>function函数： {{append1()}}</p>
            <p>function函数： {{append1()}}</p>
            <p>function函数： {{append1()}}</p>
            <button @click='uname="H!"'>修改uname</button>

            <p>message: {{message}}</p>
            <button @click='message="现在是晚上十一点五分"'>触发侦听message</button>

            <p>{{user.username}}</p>
            <button @click="changeUsername">修改username</button>

        </div>
        <script>
            const Counter = {
                data:function(){
                    return {
                        num:120,
                        uname:"hello world!",
                        msg:"<h2>Hello Vue</h2>",
                        url:"https://p0.ifengimg.com/ifeng/index/20150921/ifengLogo.png",
                        message:"2022",
                        user:{
                            username:"超人"
                        }
                    }
                },
                computed:{ //computed 是Vue的计算属性
                    //每一个计算属性中都有一个getter/setter方法
                    append(){
                        console.log("执行一次计算属性")
                        return this.uname+ '， Hi world' //依赖属性依赖uname， 如果uname不变，那么计算属性就不变。
                    }
                },
                methods:{
                    append1(){
                        console.log("执行一次function")
                        return this.uname + ", Hi,world!"
                    },
                    changeUsername(){
                        this.user.username="富贵"
                    }
                },
                watch:{
                    //注意，这里的函数名称message要和data中的属性对应，表述对某个属性的侦听
                    //第一种写法
                    // message(newValue, oldValue){
                    //     console.log(oldValue);
                    //     console.log(newValue);
                    //     //在这里可以执行复杂的操作，后者请求后台请求等。
                        
                    // }
                    //这是第二种写法, handler 这个方法名称是固定的。
                    message:{
                        immediate:true,//表示初始化时就调用函数，就是handler 函数， 
                        handler:function(newValue, oldValue){
                            if(newValue.length<5 || newValue.length>10){
                                console.log("message 不合法");
                            }
                        }
                    },
                    //这种写法不起作用，因为watch不能使用在对象的属性上，需要使用深度监听
                    // user:function(newValue){
                    //     console.log(newValue);
                    // }
                    //深度监听
                    // user:{
                    //     handler:function(newValue){
                    //         console.log(newValue);
                    //     },
                    //     deep: true,// true 表示深度监听，会对像（这里就是指user对象）属性一层一层都加上监听器，但是我们这里只想对username侦听，但是这么些每个属性都有侦听器，性能不好。
                    // }
                    "user.username":{
                        handler:function(newValue){
                            console.log("新名称： "+newValue);
                        },
                        deep: true,// true 表示深度监听，会对像（这里就是指user对象）属性一层一层都加上监听器，但是我们这里只想对username侦听，但是这么些每个属性都有侦听器，性能不好。
                    }
                }
                
            }
            //Vue 是Vue框架已经定义好的一个对象
            //createApp 方法用来创建一个应用，mount方法表示把创建的应用与html代码关联起来。
            let app = Vue.createApp(Counter).mount('#counter')
            console.log(app)
            
        </script>
    </body>
</html>